package com.superhelper.superhelper_web.common.datasource;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

public class DataSourceAdvice implements MethodBeforeAdvice,
		AfterReturningAdvice, ThrowsAdvice {
	protected Logger log = LoggerFactory.getLogger(this.getClass());

	@Override
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		boolean isMaster = false;
		String db = "DB1";
		MultiDB dsMaster = method.getAnnotation(MultiDB.class); // 指定数据库或者主从
		if (dsMaster != null) {
			isMaster = true;
			String assignDb = dsMaster.value();
			if (StringUtils.isNotBlank(assignDb)) {
				db = assignDb;
			}
		} else { // 根据ibatis注解指定主从

			Annotation array[] = method.getAnnotations();
			for (Annotation an : array) {
				if (an instanceof Insert || an instanceof Update
						|| an instanceof Delete) {
					isMaster = true;
					break;
				} else if (an instanceof Select) {
					isMaster = false;
					break;
				}
			}
		}
		String dataSourceKey = isMaster ? "master" + StringUtils.upperCase(db)
				: "slave" + StringUtils.upperCase(db);
		DataSourceSwitcher.setDataSource(dataSourceKey);
	}

	// 方法执行完之后被调用
	@Override
	public void afterReturning(Object arg0, Method method, Object[] args,
			Object target) throws Throwable {
		DataSourceSwitcher.clear();
	}

	// 抛出Exception之后被调用
	public void afterThrowing(Method method, Object[] args, Object target,
			Exception ex) throws Throwable {
		DataSourceSwitcher.clear();
	}

	/**
	 * 根据对象和属性名得到 属性
	 */
	private Object getFieldByObjectAndFileName(Object targetObj, String fileName)
			throws Exception {
		String tmp[] = fileName.split("\\.");
		Object arg = targetObj;
		Method methdo = arg.getClass().getDeclaredMethod(
				getGetterNameByFiledName(tmp[1]));
		return methdo.invoke(arg);
	}

	/**
	 * 根据属性名 得到该属性的getter方法名
	 */
	private String getGetterNameByFiledName(String fieldName) {
		return "get" + fieldName.substring(0, 1).toUpperCase()
				+ fieldName.substring(1);
	}
}
